/**
 ****************************************************************************************************
 * @file        key.c
 * @version     V1.0
 * @brief       按键输入 驱动代码
 ****************************************************************************************************
 * @attention   Waiken-Smart 慧勤智远
 *
 * 实验平台:    GD32H759IMT6小系统板
 *
 ****************************************************************************************************
 */
 
#include "key.h"
#include <stdint.h>

#include "gd32h7xx_rcu.h"
#include "gd32h7xx_adc.h"
#include "gd32h7xx_axiim.h"
#include "gd32h7xx_can.h"
#include "gd32h7xx_cau.h"
#include "gd32h7xx_cmp.h"
#include "gd32h7xx_cpdm.h"
#include "gd32h7xx_crc.h"
#include "gd32h7xx_ctc.h"
#include "gd32h7xx_dac.h"
#include "gd32h7xx_dbg.h"
#include "gd32h7xx_dci.h"
#include "gd32h7xx_dma.h"
#include "gd32h7xx_edout.h"
#include "gd32h7xx_efuse.h"
#include "gd32h7xx_enet.h"
#include "gd32h7xx_exmc.h"
#include "gd32h7xx_exti.h"
#include "gd32h7xx_fac.h"
#include "gd32h7xx_fmc.h"
#include "gd32h7xx_fwdgt.h"
#include "gd32h7xx_gpio.h"
#include "gd32h7xx_hau.h"
#include "gd32h7xx_hpdf.h"
#include "gd32h7xx_hwsem.h"
#include "gd32h7xx_i2c.h"
#include "gd32h7xx_ipa.h"
#include "gd32h7xx_lpdts.h"
#include "gd32h7xx_mdio.h"
#include "gd32h7xx_mdma.h"
#include "gd32h7xx_misc.h"
#include "gd32h7xx_ospi.h"
#include "gd32h7xx_ospim.h"
#include "gd32h7xx_pmu.h"
#include "gd32h7xx_rameccmu.h"
#include "gd32h7xx_rcu.h"
#include "gd32h7xx_rspdif.h"
#include "gd32h7xx_rtc.h"
#include "gd32h7xx_rtdec.h"
#include "gd32h7xx_sai.h"
#include "gd32h7xx_sdio.h"
#include "gd32h7xx_spi.h"
#include "gd32h7xx_syscfg.h"
#include "gd32h7xx_timer.h"
#include "gd32h7xx_tli.h"
#include "gd32h7xx_tmu.h"
#include "gd32h7xx_trigsel.h"
#include "gd32h7xx_trng.h"
#include "gd32h7xx_usart.h"
#include "gd32h7xx_vref.h"
#include "gd32h7xx_wwdgt.h"

/**
 * @brief       按键初始化函数
 * @param       无
 * @retval      无
 */
void key_init(void)
{
    rcu_periph_clock_enable(KEY0_GPIO_CLK);     /* 使能KEY0时钟 */
    rcu_periph_clock_enable(WKUP_GPIO_CLK);     /* 使能WKUP时钟 */
    
    gpio_mode_set(KEY0_GPIO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, KEY0_GPIO_PIN);  /* KEY0引脚模式设置,下拉输入 */
    
    gpio_mode_set(WKUP_GPIO_PORT, GPIO_MODE_INPUT, GPIO_PUPD_PULLDOWN, WKUP_GPIO_PIN);  /* WKUP引脚模式设置,下拉输入 */  	
}

/**
 * @brief       按键扫描函数
 * @note        该函数有响应优先级(同时按下多个按键): WK_UP > KEY0!!
 * @param       mode:0 / 1, 具体含义如下:
 *   @arg       0,  不支持连续按(当按键按下不放时, 只有第一次调用会返回键值,
 *                  必须松开以后, 再次按下才会返回其他键值)
 *   @arg       1,  支持连续按(当按键按下不放时, 每次调用该函数都会返回键值)
 * @retval      键值, 定义如下:
 *              KEY0_PRES, 1, KEY0按下
 *              WKUP_PRES, 2, WKUP按下
 */
uint8_t key_scan(uint8_t mode)
{
    static uint8_t key_up = 1;  /* 按键按松开标志 */
    uint8_t keyval = 0;

    if (mode) key_up = 1;       /* 支持连按 */
  
    if (key_up && (KEY0 == 1 || WK_UP == 1))     /* 按键松开标志为1, 且有任意一个按键按下了 */
    {
        usleep(10*1000);           /* 10ms，去抖动 */
        key_up = 0;

        if (KEY0 == 1)  keyval = KEY0_PRES;
      
        if (WK_UP == 1) keyval = WKUP_PRES;
    }
    else if (KEY0 == 0 && WK_UP == 0)            /* 没有任何按键按下, 标记按键松开 */
    {
        key_up = 1;
    }

    return keyval;              /* 返回键值 */
}
